package com.realtyreg.webview.controller;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;
import com.realtyreg.common.exception.BusinessException;
import com.realtyreg.common.exception.ResourceNotFoundException;
import com.realtyreg.domain.entity.users.User;
import com.realtyreg.service.UserService;
import com.realtyreg.service.form.PasswordForm;
import com.realtyreg.webview.form.ForgetPassword;
import com.realtyreg.webview.message.MessageSaver;
import com.realtyreg.webview.message.MessageType;

import javax.validation.Valid;
import java.util.Locale;

/**
 * Created by Petro 22.12.12 23:32
 */
@Controller
@RequestMapping("/recoverPass")
public class RecoverPassController {
    private static final Logger LOG = Logger.getLogger(RecoverPassController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private MessageSaver messageSaver;


    //забыли пароль GET
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String sendMailForm(Model model) {
        model.addAttribute(new ForgetPassword());
        return "recoverPassInit";
    }

    //забыли пароль POST
    @RequestMapping(value = "", method = RequestMethod.POST)
    public String sendMail(@Valid @ModelAttribute ForgetPassword forgetPassword, BindingResult result, Model model, Locale locale, SessionStatus status) {
        if (result.hasErrors()) {
            return "recoverPassInit";
        }
        String email = forgetPassword.getEmail();
        User user = userService.findByEmail(email);
        if (user == null) {
            result.addError(new ObjectError("forgetPassword", new String[]{"recover.pass.email.not.exist"}, null, null));
            return "recoverPassInit";
        }
        userService.createNewPasswordToken(user);
        status.setComplete();
        messageSaver.saveMessage(model, MessageType.SUCCESS, "recover.pass.mail.sent", locale);
        return "recoverPassMailSent";
    }

    //изменение забытого пароля GET
    @RequestMapping(value = "/{id}/{token}", method = RequestMethod.GET)
    public String changePassForm(@PathVariable Long id, @PathVariable String token, Model model) {
        checkToken(id, token);

        model.addAttribute(new PasswordForm());
        return "recoverPassChange";
    }

    //изменение забытого пароля POST
    @RequestMapping(value = "/{id}/{token}", method = RequestMethod.POST)
    public String changePass(@PathVariable Long id, @PathVariable String token, @Valid @ModelAttribute PasswordForm passwordForm, BindingResult result, Model model, Locale locale, SessionStatus status) {
        User user = checkToken(id, token);

        if (result.hasErrors()) {
            return "recoverPassChange";
        }

        userService.saveNewPassword(user, passwordForm.getNewPassword());
        status.setComplete();
        messageSaver.saveMessage(model, MessageType.SUCCESS, "recover.pass.change.success", locale);
        return "recoverPassChangeSuccess";
    }

    private User checkToken(Long id, String token) {
        User user = userService.findOne(id);
        if (user == null)
            throw new ResourceNotFoundException(String.format("Пользователь id=%s не найден.", id));

        String savedToken = user.getConfirmToken();
        if (StringUtils.isEmpty(savedToken))
            throw new BusinessException(String.format("Ошибка при восстановлении пароля: пользователь не инициировал восстановление пароля. Пользователь %s.", user));
        if (!savedToken.equals(token))
            throw new BusinessException(String.format("Ошибка при восстановлении пароля: токены не совпадают. Пользователь %s, ожидается токен '%s', пришел '%s'.", user, savedToken, token));

        return user;
    }
}
